/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2012/07/14
* File: Declare.h
* Blog: http://www.cnblogs.com/zengqh/
**/

#ifndef Declare_h__
#define Declare_h__

class Effect;
class GraphicsBuffer;
class RenderSystem;
class Texture;
class GLSLEffect;
class OGLGraphicsBuffer;
class OGLRenderSystem;
class OGLTexture2D;
class SceneNode;
class SceneManager;
class MaterialData;
class LightData;
class TextureLayer;
class SceneNode;
class CameraSceneNode;
class LightSceneNode;
class SkyboxSceneNode;
class CreateDeviceParams;
class Device;
class DeviceWin32;
class RenderTarget;
class RenderWindow;
class RenderWin32;
class RenderTargetListener;
class InputSystem;
class FrameListener;
class RawSceneNode;
class EffectService;
class RenderView;
class RenderTarget;
class DepthStencilRenderTarget;
class OGLDepthStencilRenderTarget;
class FrameBuffer;
class OGLFrameBuffer;
class OGLFBOTexture2D;
class AniKeyFrame;
class AnimationTrack;
class AnimationSceneNode;

/* in fact, we can get the max texture support by
 * glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num),
 * but we simplify it here.
 */
enum { MaxTextureSupport = 8 };
enum { MaxLightSupport = 8};

enum TextureType
{
	TT_8_BITS,
	TT_16_BITS,
	TT_24_BITS,
	TT_32_BITS,
	TT_INVALID
};

enum LightType
{
	LT_POINT,
	LT_SPOT,
	LT_DIRECTIONAL
};

enum TEXTURE_CLAMP
{
	//! Texture repeats
	ETC_REPEAT = 0,
	//! Texture is clamped to the last pixel
	ETC_CLAMP,
	//! Texture is clamped to the edge pixel
	ETC_CLAMP_TO_EDGE,
	//! Texture is clamped to the border pixel (if exists)
	ETC_CLAMP_TO_BORDER,
	//! Texture is alternatingly mirrored (0..1..0..1..0..)
	ETC_MIRROR,
	//! Texture is mirrored once and then clamped (0..1..0)
	ETC_MIRROR_CLAMP,
	//! Texture is mirrored once and then clamped to edge
	ETC_MIRROR_CLAMP_TO_EDGE,
	//! Texture is mirrored once and then clamped to border
	ETC_MIRROR_CLAMP_TO_BORDER
};

//! Comparison function, e.g. for depth buffer test
enum COMPARISON_FUNC
{
	//! Test never succeeds, this equals disable
	ECFN_NEVER=0,
	//! <= test, default for e.g. depth test
	ECFN_LESSEQUAL=1,
	//! Exact equality
	ECFN_EQUAL=2,
	//! exclusive less comparison, i.e. <
	ECFN_LESS,
	//! Succeeds almost always, except for exact equality
	ECFN_NOTEQUAL,
	//! >= test
	ECFN_GREATEREQUAL,
	//! inverse of <=
	ECFN_GREATER,
	//! test succeeds always
	ECFN_ALWAYS
};

enum TransformState
{
	TS_View = 0,
	TS_World,
	TS_Projection,
	TS_Texture0,
	TS_Texture1,
	TS_Texture2,
	TS_Texture3,
	TS_Texture4,
	TS_Texture5,
	TS_Texture6,
	TS_Texture7,
	TS_Count
};

enum FogState
{
	FT_Exp = 0,
	FT_Linear,
	FT_Exp2
};

enum RSState
{
	RS_OGL = 0,
	RS_OGLES2,
	RS_DX9,
	RS_SOFT
};

enum FVFState
{
	FVF_V3F  = 0x1,
	FVF_V2F  = 0x2,
	FVF_C4UB = 0x4,
	FVF_T2F  = 0x8,
	FVF_N3F  = 0x10,

	FVF_V2F_T2F = FVF_V2F | FVF_T2F,
	FVF_V3F_T2F = FVF_V3F | FVF_T2F,
	FVF_V2F_C4UB = FVF_V2F | FVF_C4UB,
	FVF_V3F_C4UB = FVF_V3F | FVF_C4UB,
	FVF_V2F_C4UB_T2F = FVF_V2F | FVF_C4UB | FVF_T2F,
	FVF_V3F_C4UB_T2F = FVF_V3F | FVF_C4UB | FVF_T2F,
	FVF_V3F_N3F_T2F = FVF_V3F | FVF_N3F | FVF_T2F,
};

enum PrimitiveState
{
	//! All vertices are non-connected points.
	PT_POINTS=0,

	//! All vertices form a single connected line.
	PT_LINE_STRIP,

	//! Just as LINE_STRIP, but the last and the first vertex is also connected.
	PT_LINE_LOOP,

	//! Every two vertices are connected creating n/2 lines.
	PT_LINES,

	//! After the first two vertices each vertex defines a new triangle.
	//! Always the two last and the new one form a new triangle.
	PT_TRIANGLE_STRIP,

	//! After the first two vertices each vertex defines a new triangle.
	//! All around the common first vertex.
	PT_TRIANGLE_FAN,

	//! Explicitly set all vertices for each triangle.
	PT_TRIANGLES,

	//! After the first two vertices each further tw vetices create a quad with the preceding two.
	PT_QUAD_STRIP,

	//! Every four vertices create a quad.
	PT_QUADS,

	//! Just as LINE_LOOP, but filled.
	PT_POLYGON,

	//! The single vertices are expanded to quad billboards on the GPU.
	PT_POINT_SPRITES
};

enum BufferUsage
{
	BU_Static,
	BU_Dynamic
};
enum BufferAccess
{
	BA_Read_Only,
	BA_Write_Only,
	BA_Read_Write
};

enum BufferState
{
	BS_VERTEX_BUFFER,
	BS_INDEX_BUFFER,
	BS_COUNT
};

enum DeviceType
{
	DT_SOFTWARE,
	DT_OPENGL,
	DT_DIRECT3D9,
	DT_COUNT
};

static inline char* textReadFromFile(const std::string& file_name)
{
	char* content = NULL;

	if (!file_name.empty())
	{
		FILE* file_handle = NULL;
		file_handle = fopen(file_name.c_str(), "r");
		if (file_handle == NULL)
		{
			return content;
		}

		fseek(file_handle, 0, SEEK_END);
		u32 file_size = ftell(file_handle);
		fseek(file_handle, 0, SEEK_SET);

		if (file_size > 0)
		{
			content = (char*)malloc(sizeof(char) * (file_size + 1));
			memset(content, 0x0, sizeof(char) * (file_size + 1));
			u32 read_size = fread(content, sizeof(char), file_size, file_handle);
			content[read_size] = '\0';
		}

		fclose(file_handle);
	}

	return content;
}

#endif	/* Declare_h__ */